<template>
  <div class="text-viewer-container">
    <!-- 工具栏 -->
    <div class="text-toolbar" >
      <div class="toolbar-left">
        <el-button @click="handleSaveFile" :disabled="!hasChanges">
          <el-icon><Check /></el-icon>
          保存文件
        </el-button>
      </div>
    </div>

    <!-- 文本编辑区域 -->
    <div class="text-content">
      <div class="text-editor-wrapper">
        <textarea
          ref="textAreaRef"
          v-model="textContent"
          class="text-editor"
          placeholder="请输入文本内容..."
          @input="handleTextChange"
          @keydown="handleKeyDown"
        ></textarea>
      </div>
      
      <!-- 行号显示 -->
      <div class="line-numbers" v-if="showLineNumbers">
        <div 
          v-for="line in lineCount" 
          :key="line" 
          class="line-number"
        >
          {{ line }}
        </div>
      </div>
    </div>

    <!-- 状态栏 -->
    <div class="text-statusbar">
      <div class="status-left">
        <span class="status-item">行: {{ currentLine }}</span>
        <span class="status-item">列: {{ currentColumn }}</span>
        <span class="status-item">字符: {{ textContent.length }} ({{ fileSize }})</span>
        <span class="status-item">编码: {{ encoding }}</span>
      </div>
      <div class="status-right">
        <span class="status-item">{{ filePath || '未保存' }}</span>
      </div>
    </div>

    <!-- 文件上传对话框 -->
    <input
      ref="fileInputRef"
      type="file"
      accept=".txt,.md,.js,.ts,.vue,.html,.css,.json,.xml,.log"
      style="display: none"
      @change="onFileChange"
    />

    <!-- 查找替换对话框 -->
    <el-dialog
      v-model="findReplaceVisible"
      title="查找与替换"
      width="500px"
      :close-on-click-modal="false"
    >
      <el-form :model="findReplaceForm" label-width="80px">
        <el-form-item label="查找">
          <el-input 
            v-model="findReplaceForm.findText" 
            placeholder="请输入要查找的文本"
            @keyup.enter="handleFindNext"
          />
        </el-form-item>
        <el-form-item label="替换为">
          <el-input 
            v-model="findReplaceForm.replaceText" 
            placeholder="请输入要替换的文本"
          />
        </el-form-item>
        <el-form-item>
          <el-checkbox v-model="findReplaceForm.matchCase">区分大小写</el-checkbox>
          <el-checkbox v-model="findReplaceForm.matchWholeWord">全字匹配</el-checkbox>
        </el-form-item>
      </el-form>
      
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="handleFindPrev">上一个</el-button>
          <el-button @click="handleFindNext">下一个</el-button>
          <el-button @click="handleReplaceCurrent">替换</el-button>
          <el-button @click="handleReplaceAll">全部替换</el-button>
          <el-button @click="findReplaceVisible = false">关闭</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted, onUnmounted, nextTick, watch } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { 
  Document, 
  FolderOpened, 
  Check, 
  RefreshLeft, 
  RefreshRight, 
  Search, 
  Edit, 
  FullScreen 
} from '@element-plus/icons-vue';
import { createFileWithContent, formatFileSize } from "../../util/fileUtils.ts";

// 定义组件props
interface Props {
  initContent?: string;
  fileName?: string;
}

const props = withDefaults(defineProps<Props>(), {
  initContent: '',
  fileName: ''
});

// 定义组件emits
const emit = defineEmits<{
  contentChange: [content: string];
  save: [content: string, fileName: string];
}>();

// 暴露方法给父组件
defineExpose({
  getContent: () => textContent.value,
  setContent: (content: string) => {
    textContent.value = content;
    hasChanges.value = false;
    nextTick(() => {
      updateCursorPosition();
    });
  },
  getFileName: () => filePath.value,
  setFileName: (fileName: string) => {
    filePath.value = fileName;
  },
  hasUnsavedChanges: () => hasChanges.value,
  clearChanges: () => {
    hasChanges.value = false;
  }
});

// 响应式数据
const textAreaRef = ref<HTMLTextAreaElement>();
const fileInputRef = ref<HTMLInputElement>();
const textContent = ref(props.initContent || '');
const hasChanges = ref(false);
const canUndo = ref(false);
const canRedo = ref(false);
const showLineNumbers = ref(true);
const encoding = ref('UTF-8');
const filePath = ref(props.fileName);
const currentLine = ref(1);
const currentColumn = ref(1);
const findReplaceVisible = ref(false);
const isFullscreen = ref(false);

// 查找替换表单
const findReplaceForm = reactive({
  findText: '',
  replaceText: '',
  matchCase: false,
  matchWholeWord: false,
});

// 计算属性
const lineCount = computed(() => {
  if(textContent.value){
    const lines = textContent.value.split('\n');
    return Array.from({ length: lines.length }, (_, i) => i + 1);
  }
  return [];
});

// 文件大小计算
const fileSize = computed(() => {
  const blob = new Blob([textContent.value]);
  return formatFileSize(blob.size);
});

// 新建文件
const handleNewFile = () => {
  if (hasChanges.value) {
    ElMessageBox.confirm('当前文件有未保存的更改，确定要新建文件吗？', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    }).then(() => {
      textContent.value = '';
      filePath.value = '';
      hasChanges.value = false;
      ElMessage.success('新建文件成功');
    }).catch(() => {
      // 用户取消
    });
  } else {
    textContent.value = '';
    filePath.value = '';
    hasChanges.value = false;
    ElMessage.success('新建文件成功');
  }
};

// 打开文件
const handleOpenFile = () => {
  fileInputRef.value?.click();
};

// 文件选择处理
const onFileChange = (event: Event) => {
  const target = event.target as HTMLInputElement;
  const file = target.files?.[0];
  
  if (file) {
    const reader = new FileReader();
    reader.onload = (e) => {
      const content = e.target?.result as string;
      textContent.value = content;
      filePath.value = file.name;
      hasChanges.value = false;
      ElMessage.success('文件打开成功');
    };
    reader.onerror = () => {
      ElMessage.error('文件读取失败');
    };
    reader.readAsText(file, encoding.value);
    
    // 清空文件选择
    target.value = '';
  }
};

// 保存文件
const handleSaveFile = () => {
  if (!textContent.value.trim()) {
    ElMessage.warning('没有内容可保存');
    return;
  }
  const fileName = filePath.value || '新建文件.txt';
  emit('save', textContent.value, fileName);
};

// 撤销
const handleUndo = () => {
  if (textAreaRef.value) {
    document.execCommand('undo');
  }
};

// 重做
const handleRedo = () => {
  if (textAreaRef.value) {
    document.execCommand('redo');
  }
};

// 查找
const handleFind = () => {
  findReplaceVisible.value = true;
  nextTick(() => {
    // 聚焦到查找输入框
    const findInput = document.querySelector('.el-dialog input') as HTMLInputElement;
    if (findInput) {
      findInput.focus();
    }
  });
};

// 替换
const handleReplace = () => {
  findReplaceVisible.value = true;
  nextTick(() => {
    // 聚焦到替换输入框
    const replaceInput = document.querySelectorAll('.el-dialog input')[1] as HTMLInputElement;
    if (replaceInput) {
      replaceInput.focus();
    }
  });
};

// 查找下一个
const handleFindNext = () => {
  if (!findReplaceForm.findText) {
    ElMessage.warning('请输入要查找的文本');
    return;
  }
  
  // 实现查找逻辑
  console.log('查找下一个:', findReplaceForm.findText);
  ElMessage.info('查找功能开发中...');
};

// 查找上一个
const handleFindPrev = () => {
  if (!findReplaceForm.findText) {
    ElMessage.warning('请输入要查找的文本');
    return;
  }
  
  // 实现查找逻辑
  console.log('查找上一个:', findReplaceForm.findText);
  ElMessage.info('查找功能开发中...');
};

// 替换当前选中
const handleReplaceCurrent = () => {
  if (!findReplaceForm.findText) {
    ElMessage.warning('请输入要查找的文本');
    return;
  }
  
  // 实现替换逻辑
  console.log('替换:', findReplaceForm.findText, '->', findReplaceForm.replaceText);
  ElMessage.info('替换功能开发中...');
};

// 全部替换
const handleReplaceAll = () => {
  if (!findReplaceForm.findText) {
    ElMessage.warning('请输入要查找的文本');
    return;
  }
  
  // 实现全部替换逻辑
  const regex = new RegExp(
    findReplaceForm.findText, 
    findReplaceForm.matchCase ? 'g' : 'gi'
  );
  textContent.value = textContent.value.replace(regex, findReplaceForm.replaceText);
  hasChanges.value = true;
  ElMessage.success('全部替换完成');
};

// 文本变化处理
const handleTextChange = () => {
  hasChanges.value = true;
  updateCursorPosition();
  
  // 向父组件发送内容变化事件
  emit('contentChange', textContent.value);
};

// 键盘事件处理
const handleKeyDown = (event: KeyboardEvent) => {
  // Ctrl+S 保存
  if (event.ctrlKey && event.key === 's') {
    event.preventDefault();
    handleSaveFile();
  }
  
  // Ctrl+F 查找
  if (event.ctrlKey && event.key === 'f') {
    event.preventDefault();
    handleFind();
  }
  
  // Ctrl+H 替换
  if (event.ctrlKey && event.key === 'h') {
    event.preventDefault();
    handleReplace();
  }
  
  // Ctrl+Z 撤销
  if (event.ctrlKey && event.key === 'z') {
    event.preventDefault();
    handleUndo();
  }
  
  // Ctrl+Y 重做
  if (event.ctrlKey && event.key === 'y') {
    event.preventDefault();
    handleRedo();
  }
};

// 更新光标位置
const updateCursorPosition = () => {
  if (textAreaRef.value) {
    const textarea = textAreaRef.value;
    const cursorPos = textarea.selectionStart;
    const textBeforeCursor = textarea.value.substring(0, cursorPos);
    if(textBeforeCursor){
    const lines = textBeforeCursor.split('\n');
      currentLine.value = lines.length;
      currentColumn.value = lines[lines.length - 1].length + 1;
    }
  }
};

// 全屏切换
const toggleFullscreen = () => {
  if (!document.fullscreenElement) {
    document.documentElement.requestFullscreen();
    isFullscreen.value = true;
  } else {
    document.exitFullscreen();
    isFullscreen.value = false;
  }
};

// 监听光标位置变化
const handleCursorChange = () => {
  if (textAreaRef.value) {
    textAreaRef.value.addEventListener('click', updateCursorPosition);
    textAreaRef.value.addEventListener('keyup', updateCursorPosition);
  }
};

// 监听props变化
watch(() => props.initContent, (newContent) => {
  if (newContent !== undefined) {
    textContent.value = newContent;
    hasChanges.value = false;
    nextTick(() => {
      updateCursorPosition();
    });
  }
});

watch(() => props.fileName, (newFileName) => {
  if (newFileName !== undefined) {
    filePath.value = newFileName;
  }
});

// 生命周期
onMounted(() => {
  handleCursorChange();
  
  // 如果有初始内容，更新光标位置
  if (props.initContent) {
    nextTick(() => {
      updateCursorPosition();
    });
  }
});

onUnmounted(() => {
  if (textAreaRef.value) {
    textAreaRef.value.removeEventListener('click', updateCursorPosition);
    textAreaRef.value.removeEventListener('keyup', updateCursorPosition);
  }
});
</script>

<style scoped>
.text-viewer-container {
  height: 100%;
  display: flex;
  flex-direction: column;
  background: #f5f5f5;
}

.text-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 16px;
  background: white;
  border-bottom: 1px solid #e4e7ed;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.toolbar-left {
  display: flex;
  align-items: center;
  gap: 8px;
}

.toolbar-right {
  display: flex;
  align-items: center;
  gap: 8px;
}

.text-content {
  flex: 1;
  display: flex;
  background: white;
  margin: 8px;
  border-radius: 4px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.text-editor-wrapper {
  flex: 1;
  position: relative;
}

.text-editor {
  width: 100%;
  height: 100%;
  border: none;
  outline: none;
  resize: none;
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  font-size: 14px;
  line-height: 1.5;
  padding: 16px;
  background: #fafafa;
  color: #333;
}

.text-editor:focus {
  background: white;
}

.line-numbers {
  width: 60px;
  background: #f0f0f0;
  border-right: 1px solid #e4e7ed;
  padding: 16px 8px;
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  font-size: 12px;
  color: #999;
  text-align: right;
  user-select: none;
}

.line-number {
  height: 21px;
  line-height: 21px;
  padding-right: 8px;
}

.text-statusbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 4px 16px;
  background: white;
  border-top: 1px solid #e4e7ed;
  font-size: 12px;
  color: #666;
}

.status-left {
  display: flex;
  align-items: center;
  gap: 16px;
}

.status-right {
  display: flex;
  align-items: center;
}

.status-item {
  padding: 2px 8px;
  border-radius: 2px;
  background: #f5f5f5;
}

.dialog-footer {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .text-toolbar {
    flex-direction: column;
    gap: 8px;
    padding: 8px;
  }
  
  .toolbar-left,
  .toolbar-right {
    justify-content: center;
  }
  
  .text-content {
    margin: 4px;
  }
  
  .line-numbers {
    width: 40px;
    font-size: 10px;
  }
}

/* 全屏样式 */
.text-viewer-container:fullscreen {
  background: white;
}

.text-viewer-container:fullscreen .text-toolbar {
  position: sticky;
  top: 0;
  z-index: 1000;
}

.text-viewer-container:fullscreen .text-statusbar {
  position: sticky;
  bottom: 0;
  z-index: 1000;
}
</style>
